import { createTextElement, insertBefore, setAttribute } from './dom'
import { createElement } from './dom'
import { forEach } from './utils'

export function createVnode(vm, ast) {
  const {
    tagName,
    attrs,
    children,
    listener,
    props,
    value,
    reactive,
    directive
  } = ast
  const childrenVnode = []
  children?.forEach(child => {
    const vnode = createVnode(vm, child)
    vnode && childrenVnode.push(vnode)
  })
  return h({
    vm,
    tag: tagName,
    attrs,
    children: childrenVnode,
    listener,
    props,
    value,
    reactive,
    directive
  })
}

export function h({
  vm,
  tag,
  attrs,
  children,
  listener,
  props,
  value,
  reactive,
  directive
}) {
  if (tag == 'text' && reactive) {
    value = vm.data[value]
  }
  for (let key in directive) {
    if (directive.hasOwnProperty(key)) {
      if (key == 'if' && !vm.data[directive[key]]) {
        return
      }
    }
  }
  return {
    tag,
    attrs,
    children,
    listener,
    props,
    el: null,
    value,
    reactive
  }
}

export function patch(container, vnode, oldVnode) {
  if (!oldVnode) {
    const el =
      vnode.tag !== 'text'
        ? createElement(vnode.tag)
        : createTextElement(vnode.value)
    patchAttrs(el, vnode)
    forEach(vnode.children, child => {
      patch(el, child)
    })
    vnode.el = el
    insertBefore(container, el)
  } else {
    if (sameNode(vnode, oldVnode)) {
      patchAttrs(oldVnode.el, vnode)
      forEach(vnode.children, child => {
        patch(oldVnode.el, child)
      })
    } else {
    }
  }
}
export function sameNode(vnode, oldVnode) {
  return vnode.tag === oldVnode && vnode.key === oldVnode.key
}
export function patchAttrs(el, vnode) {
  forEach(vnode.attrs, (value, name) => {
    setAttribute(el, name, value)
  })
}
